#网络编程
#基于UDP
# # 服务端
# import socket
# server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# server.bind(('127.0.0.1', 8002))
# while True:
#     data, (host, port) = server.recvfrom(1024) # 阻塞
#     print(data, host, port)
#     server.sendto("好的".encode('utf-8'), (host, port))

# 客户端
# import socket
# client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# while True:
#     text = input("请输入要发送的内容：")
#     if text.upper() == 'Q':
#         break
#     client.sendto(text.encode('utf-8'), ('127.0.0.1', 8002))
#     data, (host, port) = client.recvfrom(1024)
#     print(data.decode('utf-8'))
# client.close()

#基于TCP
# 服务端
# import socket
# # 1.监听本机的IP和端口
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# sock.bind(('127.0.0.1', 8001))
# sock.listen(5)
# while True:
#     # 2.等待，有人来连接（阻塞）
#     conn, addr = sock.accept()
#     # 3.等待，连接者发送消息（阻塞）
#     client_data = conn.recv(1024)
#     print(client_data)
#     # 4.给连接者回复消息
#     conn.sendall(b"hello world")
#     # 5.关闭连接
#     conn.close()
# # 6.停止服务端程序
# sock.close()

# # 客户端
# import socket
# # 1. 向指定IP发送连接请求
# client = socket.socket()
# client.connect(('127.0.0.1', 8001))
# # 2. 连接成功之后，发送消息
# client.sendall(b'hello')
# # 3. 等待，消息的回复（阻塞）
# reply = client.recv(1024)
# print(reply)
# # 4. 关闭连接
# client.close()

#粘包
# 两台电脑在进行收发数据时，其实不是直接将数据传输给对方。
# 对于发送者，执行 sendall/send 发送消息时，是将数据先发送至自己网卡的 写缓冲区 ，再由缓冲区将数据发送给到对方网卡的读缓冲区。
# 对于接受者，执行 recv 接收消息时，是从自己网卡的读缓冲区获取数据。
# 所以，如果发送者连续快速的发送了2条信息，接收者在读取时会认为这是1条信息，即：2个数据包粘在了一起。
#如何解决粘包的问题？
#
#1、每次发送的消息时，都将消息划分为 头部（固定字节长度） 和 数据 两部分。例如：头部，用4个字节表示后面数据的长度。
#2、发送数据，先发送数据的长度，再发送数据（或拼接起来再发送）。
#3、接收数据，先读4个字节就可以知道自己这个数据包中的数据长度，再根据长度读取到数据。
#4、对于头部需要一个数字并固定为4个字节，这个功能可以借助python的struct包来实现：
# import struct
# ####数值转换为固定4个字节，4个字节的范围 -214783648<= num <= 214783647 #######
# v1=struct.pack('i',199)
# print(v1)
# for i in v1:
#     print(i)
# ######4字节转换为数字#########
# v2=struct.unpack('i',v1)
# print(v2)